using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;

namespace WikiUploader.Classes.DotNetWikiBot
{
   /// <summary>Class defines custom XML URL resolver, that has a caching capability. See
   /// http://www.w3.org/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic for details.</summary>
   //[PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
   [ClassInterface(ClassInterfaceType.AutoDispatch)]
   class XmlUrlResolverWithCache : XmlUrlResolver
   {
      /// <summary>List of cached files absolute URIs.</summary>
      static readonly string[] s_CachedFilesUrIs = {
                                                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
                                                    "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent",
                                                    "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent",
                                                    "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
                                                    //http://www.mediawiki.org/xml/export-0.4/ http://www.mediawiki.org/xml/export-0.4.xsd
                                                 };
      /// <summary>List of cached files names.</summary>
      static readonly string[] s_CachedFiles = {
                                                "xhtml1-transitional.dtd",
                                                "xhtml-lat1.ent",
                                                "xhtml-symbol.ent",
                                                "xhtml-special.ent"
                                             };
      /// <summary>Local cache directory.</summary>
      static readonly string s_CacheDir = "Cache" + Path.DirectorySeparatorChar;

      /// <summary>Overriding GetEntity() function to implement local cache.</summary>
      /// <param name="absoluteUri">Absolute URI of requested entity.</param>
      /// <param name="role">User's role for accessing specified URI.</param>
      /// <param name="ofObjectToReturn">Type of object to return.</param>
      /// <returns>Returns object or requested type.</returns>
      public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
      {
         for (int i = 0; i < s_CachedFilesUrIs.Length; i++)
            if (absoluteUri.OriginalString == s_CachedFilesUrIs[i])
               return new FileStream(s_CacheDir + s_CachedFiles[i], FileMode.Open, FileAccess.Read, FileShare.Read);
         return base.GetEntity(absoluteUri, role, ofObjectToReturn);
      }
   }
}